import socket


class IRC_Class():
    """Creates a socket and defines method that allow the interaction
    with an IRC server.
    """

    def __init__(self):
        self.IRC=socket.socket()

    def login(self, server, port, nickname, password, user, channel):
        """Logins into a IRC server.
        It requires a server url and it's port, the nickname and password.
        It also requires the username and the channel to join.

        It takes care of the first ping that the server sends.

        After it logins in a IRC server, it authenticates the nickname and join
        the channel.

        Doesn't return anything.
        """

        # Do a simple check to see if the server link is correct
        if len(server.split(".")) != 3: # Should be ["irc", "freenode", "net"]
            return 1

        self.IRC.connect((server, port))
        print "Connected to server"

        self.send("NICK " + nickname)
        msg = self.IRC.recv(512)
        print "Nickgetting successful"

        self.pong(msg)
        print "Pong successful"

        self.send("USER" + 4 * (" "+user))
        self.send("NICKSERV identify " + password)
        msg=self.IRC.recv(512)
        print "User and Password successful"

        ## TODO: Should not be necessary to join a channel in the login
        ##       It should be possible to join them later
        print "Joining " + channel
        self.join(channel)
        print "Joined " + channel + " successfully"


    #######################################
    ######## IRC Related Functions ########
    #######################################

    def send(self, msg):
        """Sends a text directly to the IRC server. See the IRC protocol to
        know what to send here.
        Doesn't return anything.
        """
        self.IRC.send(msg + "\r\n")

    def pong(self, msg):
        """Sends a response to a ping command sent by the IRC server.
        Doesn't return anything.
        """
        ## TODO: Should return a error code when the same nick is already
        ##       online
        self.send("PONG %s" % msg.split()[msg.split().index("PING")+1])

    def join(self, channel):
        """Joins a channel.
        Doesn't return anything.
        """
        if channel[0] != "#":
            channel = "#" + channel
        self.send("JOIN " + channel)

    def sendChannel(self, channel, msg):
        """Sends a message to a channel.
        Doesn't return anything.
        """
        self.send("PRIVMSG " + channel + " :" + msg)

    def sendPrivmsg(self, user, msg):
        """Sends a private message to a user.
        Doesn't return anything.
        """
        self.send("PRIVMSG " + user + " :" + msg + "\r\n")

    ########################################
    ###### Parsing Related Functions #######
    ########################################

    def parseMsg(self, msg):
        try:
            return msg.split(':', 2)[2]
        except: # TODO: Find out the specific exception to catch
            return ""

    def parseUsr(self, msg):
        try:
            return msg.split('!')[0][1:]
        except: # TODO: Find out the specific exception to catch
            return ""

    def parseTarget(self, msg):
        #    pdb.set_trace()
        try:
            msg = self.parseMsg(msg)
            msg = msg.split(' ', 1)[1]
            msg = msg.replace('\r\n', '').replace('\n', '')
            msg = msg.replace(' ', '') # Is this step really necessary?
            return msg
        except: # TODO: Find out the specific exception to catch
            return ""

    def parseCmd(self, msg):
        cmd = msg.split(' ')[0][1:].replace('\r\n', '')
        return cmd
